package com.peanutplan.blog.service.impl;

import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.peanutplan.blog.annotation.SynchronizeToEs;
import com.peanutplan.blog.constant.WebConst;
import com.peanutplan.blog.dao.CollectionVoMapper;
import com.peanutplan.blog.dao.ContentVoMapper;
import com.peanutplan.blog.dao.MetaVoMapper;
import com.peanutplan.blog.dto.Types;
import com.peanutplan.blog.exception.TipException;
import com.peanutplan.blog.model.vo.CollectionVoExample;
import com.peanutplan.blog.model.vo.ContentVo;
import com.peanutplan.blog.model.vo.ContentVoExample;
import com.peanutplan.blog.service.IContentService;
import com.peanutplan.blog.service.IMetaService;
import com.peanutplan.blog.service.IRelationshipService;
import com.peanutplan.blog.utils.CommonUtil;
import com.peanutplan.blog.utils.DateUtil;
import com.peanutplan.blog.utils.SensitiveWordUtil;
import com.peanutplan.blog.utils.Tools;
import com.vdurmont.emoji.EmojiParser;

/**
 * Created by Administrator on 2017/3/13 013.
 */
@Service
public class ContentServiceImpl implements IContentService {
    private static final Logger LOGGER = LoggerFactory.getLogger(ContentServiceImpl.class);

    @Resource
    private SensitiveWordUtil sensitiveWordUtil;
    
    @Resource
    private ContentVoMapper contentDao;

    @Resource
    private MetaVoMapper metaDao;
    
    @Resource
    private CollectionVoMapper collectionDao;

    @Resource
    private IRelationshipService relationshipService;

    @Resource
    private IMetaService metasService;

    @Override
    @SynchronizeToEs(esIndex = "article", paramName = "contents", type = "create", clazz = ContentVo.class)
    public void publish(ContentVo contents) {
        if (null == contents) {
            throw new TipException("文章对象为空");
        }
        if (StringUtils.isBlank(contents.getTitle())) {
            throw new TipException("文章标题不能为空");
        }
        if (StringUtils.isBlank(contents.getContent())) {
            throw new TipException("文章内容不能为空");
        }
        int titleLength = contents.getTitle().length();
        if (titleLength > WebConst.MAX_TITLE_COUNT) {
            throw new TipException("文章标题过长");
        }
//        int contentLength = contents.getContent().length();
//        if (contentLength > WebConst.MAX_TEXT_COUNT) {
//            throw new TipException("文章内容过长");
//        }
        if (null == contents.getAuthorId()) {
            throw new TipException("请登录后发布文章");
        }
        if (StringUtils.isNotBlank(contents.getSlug())) {
            if (contents.getSlug().length() < 5) {
                throw new TipException("路径太短了");
            }
            if (!CommonUtil.isPath(contents.getSlug())) throw new TipException("您输入的路径不合法");
            ContentVoExample contentVoExample = new ContentVoExample();
            contentVoExample.createCriteria().andTypeEqualTo(contents.getType()).andStatusEqualTo(contents.getSlug());
            long count = contentDao.countByExample(contentVoExample);
            if (count > 0) throw new TipException("该路径已经存在，请重新输入");
        } else {
            contents.setSlug(null);
        }

        if(contents.getContent()!=null) {
        	contents.setContent(EmojiParser.parseToAliases(contents.getContent()));
            contents.setContent(sensitiveWordUtil.replaceSensitiveWord(contents.getContent()));
            contents.setContentText(sensitiveWordUtil.replaceSensitiveWord(contents.getContentText()));
            contents.setRemark(sensitiveWordUtil.replaceSensitiveWord(contents.getRemark()));
        }

        int time = DateUtil.getCurrentUnixTime();
        contents.setCreated(time);
        contents.setModified(time);
        contents.setHits(0);
        contents.setCommentsNum(0);

        String tags = contents.getTags();
        String categories = contents.getCategories();
        
        contentDao.insert(contents);
//        ElasticSearchUtils.addEntityDoc("article", contents.getCid(), entity);
        
        Integer cid = contents.getCid();

        metasService.saveMetas(cid, tags, Types.TAG.getType());
        metasService.saveMetas(cid, categories, Types.CATEGORY.getType());
    }

    @Override
    public PageInfo<ContentVo> getContents(Integer p, Integer limit) {
        LOGGER.debug("Enter getContents method");
        ContentVoExample example = new ContentVoExample();
        example.setOrderByClause("created desc");
        example.createCriteria().andTypeEqualTo(Types.ARTICLE.getType()).andStatusEqualTo(Types.PUBLISH.getType());
        PageHelper.startPage(p, limit);
        List<ContentVo> data = contentDao.selectByExampleWithBLOBs(example);
        PageInfo<ContentVo> pageInfo = new PageInfo<>(data);
        LOGGER.debug("Exit getContents method");
        return pageInfo;
    }
    
    @Override
    public PageInfo<ContentVo> getContents(Integer p, Integer limit, String category, String tag) {
        LOGGER.debug("Enter getContents method");
        ContentVoExample example = new ContentVoExample();
        example.setOrderByClause("created desc");
        
        ContentVoExample.Criteria criteria = example.createCriteria();
        criteria.andTypeEqualTo(Types.ARTICLE.getType()).andStatusEqualTo(Types.PUBLISH.getType());
        if(StringUtils.isNotBlank(category)) {
        	criteria.andCategoriesEqualTo(category);
        }
        if(StringUtils.isNotBlank(tag)) {
        	criteria.andTagsLike("%"+tag+"%");
        }
        
        PageHelper.startPage(p, limit);
        List<ContentVo> data = contentDao.selectByExampleWithBLOBs(example);
        PageInfo<ContentVo> pageInfo = new PageInfo<>(data);
        LOGGER.debug("Exit getContents method");
        return pageInfo;
    }

    @Override
    public ContentVo getContents(String id) {
        if (StringUtils.isNotBlank(id)) {
            if (Tools.isNumber(id)) {
                ContentVo contentVo = contentDao.selectByPrimaryKey(Integer.valueOf(id));
                if (contentVo != null) {
                    contentVo.setHits(contentVo.getHits() + 1);
                    contentDao.updateByPrimaryKey(contentVo);
                }
                return contentVo;
            } else {
                ContentVoExample contentVoExample = new ContentVoExample();
                contentVoExample.createCriteria().andSlugEqualTo(id);
                List<ContentVo> contentVos = contentDao.selectByExampleWithBLOBs(contentVoExample);
                if (contentVos.size() != 1) {
                    throw new TipException("query content by id and return is not one");
                }
                
                ContentVo c = contentVos.get(0);
                if (c != null) {
                    c.setHits(c.getHits() + 1);
                    contentDao.updateByPrimaryKey(c);
                }
                return c;
            }
        }
        return null;
    }
    
    public ContentVo getPreContents(ContentVo contents) {
    	ContentVoExample preExample = new ContentVoExample();
        preExample.setOrderByClause("created desc");
        preExample.createCriteria().andCidLessThan(contents.getCid()).andCategoriesLike("%"+contents.getCategories()+"%").andTypeEqualTo(Types.ARTICLE.getType()).andStatusEqualTo(Types.PUBLISH.getType());
        
        PageHelper.startPage(1, 1);
        List<ContentVo> list = contentDao.selectByExample(preExample);
        if(list!=null && list.size()>0) {
        	return list.get(0);
        }
        return null;
    }
    
    public ContentVo getNextContents(ContentVo contents) {
    	ContentVoExample nextExample = new ContentVoExample();
    	nextExample.setOrderByClause("created desc");
    	nextExample.createCriteria().andCidGreaterThan(contents.getCid()).andCategoriesLike("%"+contents.getCategories()+"%").andTypeEqualTo(Types.ARTICLE.getType()).andStatusEqualTo(Types.PUBLISH.getType());
        
        PageHelper.startPage(1, 1);
        List<ContentVo> list = contentDao.selectByExample(nextExample);
        if(list!=null && list.size()>0) {
        	return list.get(0);
        }
        return null;
    }

    @Override
    @SynchronizeToEs(esIndex = "article", paramName = "contentVo", type = "update", clazz = ContentVo.class)
    public void updateContentByCid(ContentVo contentVo) {
        if (null != contentVo && null != contentVo.getCid()) {
        	
        	if(contentVo.getContent()!=null) {
        		contentVo.setContent(sensitiveWordUtil.replaceSensitiveWord(contentVo.getContent()));
            	contentVo.setContentText(sensitiveWordUtil.replaceSensitiveWord(contentVo.getContentText()));
                contentVo.setRemark(sensitiveWordUtil.replaceSensitiveWord(contentVo.getRemark()));
        	}
        	
            contentDao.updateByPrimaryKeySelective(contentVo);
        }
    }

    @Override
    public PageInfo<ContentVo> getArticles(Integer mid, int page, int limit) {
        int total = metaDao.countWithSql(mid);
        PageHelper.startPage(page, limit);
        List<ContentVo> list = contentDao.findByCatalog(mid);
        PageInfo<ContentVo> paginator = new PageInfo<>(list);
        paginator.setTotal(total);
        return paginator;
    }

    @Override
    public PageInfo<ContentVo> getArticles(String keyword, Integer page, Integer limit) {
        PageHelper.startPage(page, limit);
        ContentVoExample contentVoExample = new ContentVoExample();
        ContentVoExample.Criteria criteria = contentVoExample.createCriteria();
        criteria.andTypeEqualTo(Types.ARTICLE.getType());
        criteria.andStatusEqualTo(Types.PUBLISH.getType());
        criteria.andTitleLike("%" + keyword + "%");
        contentVoExample.setOrderByClause("created desc");
        List<ContentVo> contentVos = contentDao.selectByExampleWithBLOBs(contentVoExample);
        return new PageInfo<>(contentVos);
    }

    @Override
    public PageInfo<ContentVo> getArticlesWithpage(ContentVoExample commentVoExample, Integer page, Integer limit) {
        PageHelper.startPage(page, limit);
        List<ContentVo> contentVos = contentDao.selectByExampleWithBLOBs(commentVoExample);
        return new PageInfo<>(contentVos);
    }

    @Override
    @SynchronizeToEs(esIndex = "article", paramName = "cid", type = "delete", clazz = Integer.class)
    public void deleteByCid(Integer cid) {
        ContentVo contents = this.getContents(cid + "");
        if (null != contents) {
            contentDao.deleteByPrimaryKey(cid);
            relationshipService.deleteById(cid, null);
            
            CollectionVoExample collectionFilter = new CollectionVoExample();
            collectionFilter.createCriteria().andCidEqualTo(cid);
            collectionDao.deleteByExample(collectionFilter);
        }
    }

    @Override
    public void updateCategory(String ordinal, String newCatefory) {
        ContentVo contentVo = new ContentVo();
        contentVo.setCategories(newCatefory);
        ContentVoExample example = new ContentVoExample();
        example.createCriteria().andCategoriesEqualTo(ordinal);
        contentDao.updateByExampleSelective(contentVo, example);
    }

    @Override
    @SynchronizeToEs(esIndex = "article", paramName = "contents", type = "update", clazz = ContentVo.class)
    public void updateArticle(ContentVo contents) {
        if (null == contents || null == contents.getCid()) {
            throw new TipException("文章对象不能为空");
        }
        if (StringUtils.isBlank(contents.getTitle())) {
            throw new TipException("文章标题不能为空");
        }
        if (StringUtils.isBlank(contents.getContent())) {
            throw new TipException("文章内容不能为空");
        }
        if (contents.getTitle().length() > 200) {
            throw new TipException("文章标题过长");
        }
//        if (contents.getContent().length() > 65000) {
//            throw new TipException("文章内容过长");
//        }
        if (null == contents.getAuthorId()) {
            throw new TipException("请登录后发布文章");
        }
        if (StringUtils.isBlank(contents.getSlug())) {
            contents.setSlug(null);
        }
        int time = DateUtil.getCurrentUnixTime();
        contents.setModified(time);
        Integer cid = contents.getCid();

        if(contents.getContent()!=null) {
        	contents.setContent(EmojiParser.parseToAliases(contents.getContent()));
	        contents.setContent(sensitiveWordUtil.replaceSensitiveWord(contents.getContent()));
	        contents.setContentText(sensitiveWordUtil.replaceSensitiveWord(contents.getContentText()));
	        contents.setRemark(sensitiveWordUtil.replaceSensitiveWord(contents.getRemark()));
        }
        
        contentDao.updateByPrimaryKeySelective(contents);
        relationshipService.deleteById(cid, null);
        metasService.saveMetas(cid, contents.getTags(), Types.TAG.getType());
        metasService.saveMetas(cid, contents.getCategories(), Types.CATEGORY.getType());
    }
}
